﻿/******************************************************************************              
 * Author: 671643387@qq.com                                                                                                                                            
 * @MR.Luo                                                                                      
 *****************************************************************************/

#include <stdio.h>
#if defined(__WINDOWS__)
#include <crtdbg.h>
#endif
#include <signal.h>
#include <string>
#include <boost/program_options.hpp>
#include "Common.h"
#include "EchoServer.h"
using namespace dev;
namespace po = boost::program_options;

EchoServer* g_pServer = NULL;

void signal_handler(int signal)
{
    if (signal == SIGINT)
    {
        std::cout << "Shuting down server..." << std::endl;
        g_pServer->close();
    }
}

int main(int argc, char *argv[])
{
    std::string addr;
    int port = 0;
    int backlog = 0;
    int workerCount = 0;

    po::options_description desc("allow options");
    desc.add_options()
        ("help,h", "show usage")
        ("address,a", po::value<std::string>()->default_value("0.0.0.0"), "listen address")
        ("port,p", po::value<int>()->default_value(8888), "listen port")
        ("backlog,b", po::value<int>()->default_value(5), "listen backlog")
        ("threads,t", po::value<int>()->default_value(0), "addtional threads");

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);

    if (vm.count("help"))
    {
        std::cout << desc << std::endl;
        return 0;
    }

    addr = vm["address"].as<std::string>();
    port = vm["port"].as<int>();
    backlog = vm["backlog"].as<int>();
    workerCount = vm["threads"].as<int>();

#if defined(__WINDOWS__)
    //_CrtSetBreakAlloc(156);
    WSAData wsaData;
    ::WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
	__DV_TRY
    {
        signal(SIGINT, signal_handler);

        dev::net::EventLoop loop;

        EchoServer server(loop);
        g_pServer = &server;
        server.getServer().config(dev::net::TcpServer::WORKERNUM, workerCount);
		server.getServer().config(dev::net::TcpServer::MASTERASWORKER, 1);
        server.getServer().config(dev::net::TcpServer::FRAMETIME, 0);
        server.getServer().config(dev::net::TcpServer::CONNISSIZE, CONN_SS_SIZE);
        server.getServer().config(dev::net::TcpServer::CONNOSSIZE, CONN_SS_SIZE);
        server.getServer().config(dev::net::TcpServer::LOGGER, dev::base::LoggerPtr(new dev::base::Logger()));

        assert(server.open(addr.c_str(), port, backlog));
		loop.run();
	}
	__DV_CATCH(std::exception& e)
	{
		__DV_DUMP(e);
	}

#if defined(__WINDOWS__)
    ::WSACleanup();
	_CrtDumpMemoryLeaks();
#endif

	return 0;
}
